home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / dec0.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  39KB  |  1,401 lines

  1. /***************************************************************************
  2.  
  3.   Dec0 Video emulation - Bryan McPhail, mish@tendril.co.uk
  4.  
  5. *********************************************************************
  6.  
  7.     Each game uses the MXC-06 chip to produce sprites.
  8.  
  9.     Sprite data:  The unknown bits seem to be unused.
  10.  
  11.     Byte 0:
  12.         Bit 0 : Y co-ord hi bit
  13.         Bit 1,2: ?
  14.         Bit 3,4 : Sprite height (1x, 2x, 4x, 8x)
  15.         Bit 5  - X flip
  16.         Bit 6  - Y flip
  17.         Bit 7  - Only display Sprite if set
  18.     Byte 1: Y-coords
  19.     Byte 2:
  20.         Bit 0,1,2,3: Hi bits of sprite number
  21.         Bit 4,5,6,7: (Probably unused MSB's of sprite)
  22.     Byte 3: Low bits of sprite number
  23.     Byte 4:
  24.         Bit 0 : X co-ords hi bit
  25.         Bit 1,2: ??
  26.         Bit 3: Sprite flash (sprite is displayed every other frame)
  27.         Bit 4,5,6,7:  - Colour
  28.     Byte 5: X-coords
  29.  
  30. **********************************************************************
  31.  
  32.   Palette data
  33.  
  34.     0x000 - character palettes (Sprites on Midnight R)
  35.     0x200 - sprite palettes (Characters on Midnight R)
  36.     0x400 - tiles 1
  37.       0x600 - tiles 2
  38.  
  39.     Bad Dudes, Robocop, Heavy Barrel, Hippodrome - 24 bit rgb
  40.     Sly Spy, Midnight Resistance - 12 bit rgb
  41.  
  42.   Tile data
  43.  
  44.       4 bit palette select, 12 bit tile select
  45.  
  46. **********************************************************************
  47.  
  48.  All games contain three BAC06 background generator chips, usual (software)
  49. configuration is 2 chips of 16*16 tiles, 1 of 8*8.
  50.  
  51.  Playfield control registers:
  52.    bank 0:
  53.    0:
  54.         bit 0 (0x1) set = 8*8 tiles, else 16*16 tiles
  55.         Bit 1 (0x2) unknown
  56.         bit 2 (0x4) set enables rowscroll
  57.         bit 3 (0x8) set enables colscroll
  58.         bit 7 (0x80) set in playfield 1 is reverse screen (set via dip-switch)
  59.         bit 7 (0x80) in other playfields unknown
  60.    2: unknown (00 in bg, 03 in fg+text - maybe controls pf transparency?)
  61.    4: unknown (always 00)
  62.    6: playfield shape: 00 = 4x1, 01 = 2x2, 02 = 1x4 (low 4 bits only)
  63.  
  64.    bank 1:
  65.    0: horizontal scroll
  66.    2: vertical scroll
  67.    4: Style of colscroll (low 4 bits, top 4 bits do nothing)
  68.    6: Style of rowscroll (low 4 bits, top 4 bits do nothing)
  69.  
  70. Rowscroll/Colscroll styles:
  71.     0: 256 scroll registers (Robocop)
  72.     1: 128 scroll registers
  73.     2:  64 scroll registers
  74.     3:  32 scroll registers (Heavy Barrel, Midres)
  75.     4:  16 scroll registers (Bad Dudes, Sly Spy)
  76.     5:   8 scroll registers (Hippodrome)
  77.     6:   4 scroll registers (Heavy Barrel)
  78.     7:   2 scroll registers (Heavy Barrel, used on other games but registers kept at 0)
  79.     8:   1 scroll register (ie, none)
  80.  
  81.     Values above are *multiplied* by playfield shape.
  82.  
  83. Playfield priority (Bad Dudes, etc):
  84.     In the bottommost playfield, pens 8-15 can have priority over the next playfield.
  85.     In that next playfield, pens 8-15 can have priority over sprites.
  86.  
  87. Bit 0:  Playfield inversion
  88. Bit 1:  Enable playfield mixing (for palettes 8-15 only)
  89. Bit 2:  Enable playfield/sprite mixing (for palettes 8-15 only)
  90.  
  91. Priority word (Midres):
  92.     Bit 0 set = Playfield 3 drawn over Playfield 2
  93.             ~ = Playfield 2 drawn over Playfield 3
  94.     Bit 1 set = Sprites are drawn inbetween playfields
  95.             ~ = Sprites are on top of playfields
  96.     Bit 2
  97.     Bit 3 set = ...
  98.  
  99. ***************************************************************************/
  100.  
  101. #include "driver.h"
  102. #include "vidhrdw/generic.h"
  103.  
  104. #define TEXTRAM_SIZE    0x2000    /* Size of text layer */
  105. #define TILERAM_SIZE    0x800    /* Size of background and foreground */
  106.  
  107. /* Video */
  108. unsigned char *dec0_pf1_data,*dec0_pf2_data,*dec0_pf3_data;
  109. static unsigned char *dec0_pf1_dirty,*dec0_pf3_dirty,*dec0_pf2_dirty;
  110. static struct osd_bitmap *dec0_pf1_bitmap;
  111. static int dec0_pf1_current_shape;
  112. static struct osd_bitmap *dec0_pf2_bitmap;
  113. static int dec0_pf2_current_shape;
  114. static struct osd_bitmap *dec0_pf3_bitmap;
  115. static int dec0_pf3_current_shape;
  116. static struct osd_bitmap *dec0_tf2_bitmap;
  117. static struct osd_bitmap *dec0_tf3_bitmap;
  118.  
  119. unsigned char *dec0_pf1_rowscroll,*dec0_pf2_rowscroll,*dec0_pf3_rowscroll;
  120. unsigned char *dec0_pf1_colscroll,*dec0_pf2_colscroll,*dec0_pf3_colscroll;
  121. static unsigned char dec0_pf1_control_0[8];
  122. static unsigned char dec0_pf1_control_1[8];
  123. static unsigned char dec0_pf2_control_0[8];
  124. static unsigned char dec0_pf2_control_1[8];
  125. static unsigned char dec0_pf3_control_0[8];
  126. static unsigned char dec0_pf3_control_1[8];
  127. static unsigned char *dec0_spriteram;
  128.  
  129. static int dec0_pri;
  130.  
  131. /******************************************************************************/
  132.  
  133. WRITE_HANDLER( dec0_update_sprites_w )
  134. {
  135.     memcpy(dec0_spriteram,spriteram,0x800);
  136. }
  137.  
  138. /******************************************************************************/
  139.  
  140. static void update_24bitcol(int offset)
  141. {
  142.     int r,g,b;
  143.  
  144.     r = (READ_WORD(&paletteram[offset]) >> 0) & 0xff;
  145.     g = (READ_WORD(&paletteram[offset]) >> 8) & 0xff;
  146.     b = (READ_WORD(&paletteram_2[offset]) >> 0) & 0xff;
  147.  
  148.     palette_change_color(offset / 2,r,g,b);
  149. }
  150.  
  151. WRITE_HANDLER( dec0_paletteram_rg_w )
  152. {
  153.     COMBINE_WORD_MEM(&paletteram[offset],data);
  154.     update_24bitcol(offset);
  155. }
  156.  
  157. WRITE_HANDLER( dec0_paletteram_b_w )
  158. {
  159.     COMBINE_WORD_MEM(&paletteram_2[offset],data);
  160.     update_24bitcol(offset);
  161. }
  162.  
  163. /******************************************************************************/
  164.  
  165. /* pf23priority: 1 -> pf2 transparent, pf3 not transparent */
  166. /*               0 -> pf2 not transparent, pf3 transparent */
  167. static void dec0_update_palette(int pf23priority)
  168. {
  169.     int offs;
  170.     int color,code,i;
  171.     int colmask[16];
  172.     int pal_base;
  173.  
  174.  
  175.     palette_init_used_colors();
  176.  
  177.     pal_base = Machine->drv->gfxdecodeinfo[0].color_codes_start;
  178.     for (color = 0;color < 16;color++) colmask[color] = 0;
  179.     for (offs = 0; offs < TEXTRAM_SIZE;offs += 2)
  180.     {
  181.         code = READ_WORD(&dec0_pf1_data[offs]);
  182.         color = (code & 0xf000) >> 12;
  183.         code &= 0x0fff;
  184.         colmask[color] |= Machine->gfx[0]->pen_usage[code];
  185.     }
  186.  
  187.     for (color = 0;color < 16;color++)
  188.     {
  189.         if (colmask[color] & (1 << 0))
  190.             palette_used_colors[pal_base + 16 * color] = PALETTE_COLOR_TRANSPARENT;
  191.         for (i = 1;i < 16;i++)
  192.         {
  193.             if (colmask[color] & (1 << i))
  194.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  195.         }
  196.     }
  197.  
  198.     pal_base = Machine->drv->gfxdecodeinfo[1].color_codes_start;
  199.     for (color = 0;color < 16;color++) colmask[color] = 0;
  200.     for (offs = 0; offs < TILERAM_SIZE;offs += 2)
  201.     {
  202.         code = READ_WORD(&dec0_pf2_data[offs]);
  203.         color = (code & 0xf000) >> 12;
  204.         code &= 0x0fff;
  205.         colmask[color] |= Machine->gfx[1]->pen_usage[code];
  206.     }
  207.  
  208.     for (color = 0;color < 16;color++)
  209.     {
  210.         if (colmask[color] & (1 << 0))
  211.             palette_used_colors[pal_base + 16 * color] = pf23priority ? PALETTE_COLOR_USED : PALETTE_COLOR_TRANSPARENT;
  212.         for (i = 1;i < 16;i++)
  213.         {
  214.             if (colmask[color] & (1 << i))
  215.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  216.         }
  217.     }
  218.  
  219.     pal_base = Machine->drv->gfxdecodeinfo[2].color_codes_start;
  220.     for (color = 0;color < 16;color++) colmask[color] = 0;
  221.     for (offs = 0; offs < TILERAM_SIZE;offs += 2)
  222.     {
  223.         code = READ_WORD(&dec0_pf3_data[offs]);
  224.         color = (code & 0xf000) >> 12;
  225.         code &= 0x0fff;
  226.         colmask[color] |= Machine->gfx[2]->pen_usage[code];
  227.     }
  228.  
  229.     for (color = 0;color < 16;color++)
  230.     {
  231.         if (colmask[color] & (1 << 0))
  232.             palette_used_colors[pal_base + 16 * color] = pf23priority ? PALETTE_COLOR_TRANSPARENT : PALETTE_COLOR_USED;
  233.         for (i = 1;i < 16;i++)
  234.         {
  235.             if (colmask[color] & (1 << i))
  236.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  237.         }
  238.     }
  239.  
  240.     pal_base = Machine->drv->gfxdecodeinfo[3].color_codes_start;
  241.     palette_used_colors[pal_base] = PALETTE_COLOR_TRANSPARENT; /* Always set this, for priorities to work */
  242.     for (color = 0;color < 16;color++) colmask[color] = 0;
  243.     for (offs = 0;offs < 0x800;offs += 8)
  244.     {
  245.         int x,y,sprite,multi;
  246.  
  247.         y = READ_WORD(&dec0_spriteram[offs]);
  248.         if ((y&0x8000) == 0) continue;
  249.  
  250.         x = READ_WORD(&dec0_spriteram[offs+4]);
  251.         color = (x & 0xf000) >> 12;
  252.  
  253.         multi = (1 << ((y & 0x1800) >> 11)) - 1;    /* 1x, 2x, 4x, 8x height */
  254.                                             /* multi = 0   1   3   7 */
  255.  
  256.         x = x & 0x01ff;
  257.         if (x >= 256) x -= 512;
  258.         x = 240 - x;
  259.         if (x>256) continue; /* Speedup + save colours */
  260.  
  261.         sprite = READ_WORD (&dec0_spriteram[offs+2]) & 0x0fff;
  262.  
  263.         sprite &= ~multi;
  264.  
  265.         while (multi >= 0)
  266.         {
  267.             colmask[color] |= Machine->gfx[3]->pen_usage[sprite + multi];
  268.  
  269.             multi--;
  270.         }
  271.     }
  272.  
  273.     for (color = 0;color < 16;color++)
  274.     {
  275.         for (i = 1;i < 16;i++)
  276.         {
  277.             if (colmask[color] & (1 << i))
  278.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  279.         }
  280.     }
  281.  
  282.  
  283.     if (palette_recalc())
  284.     {
  285.         memset(dec0_pf1_dirty,1,TEXTRAM_SIZE);
  286.         memset(dec0_pf2_dirty,1,TILERAM_SIZE);
  287.         memset(dec0_pf3_dirty,1,TILERAM_SIZE);
  288.     }
  289. }
  290.  
  291. /******************************************************************************/
  292.  
  293. static void dec0_drawsprites(struct osd_bitmap *bitmap,int pri_mask,int pri_val)
  294. {
  295.     int offs;
  296.  
  297.     for (offs = 0;offs < 0x800;offs += 8)
  298.     {
  299.         int x,y,sprite,colour,multi,fx,fy,inc,flash;
  300.  
  301.         y = READ_WORD(&dec0_spriteram[offs]);
  302.         if ((y&0x8000) == 0) continue;
  303.  
  304.         x = READ_WORD(&dec0_spriteram[offs+4]);
  305.         colour = x >> 12;
  306.         if ((colour & pri_mask) != pri_val) continue;
  307.  
  308.         flash=x&0x800;
  309.         if (flash && (cpu_getcurrentframe() & 1)) continue;
  310.  
  311.         fx = y & 0x2000;
  312.         fy = y & 0x4000;
  313.         multi = (1 << ((y & 0x1800) >> 11)) - 1;    /* 1x, 2x, 4x, 8x height */
  314.                                             /* multi = 0   1   3   7 */
  315.  
  316.         sprite = READ_WORD (&dec0_spriteram[offs+2]) & 0x0fff;
  317.  
  318.         x = x & 0x01ff;
  319.         y = y & 0x01ff;
  320.         if (x >= 256) x -= 512;
  321.         if (y >= 256) y -= 512;
  322.         x = 240 - x;
  323.         y = 240 - y;
  324.  
  325.         if (x>256) continue; /* Speedup */
  326.  
  327.         sprite &= ~multi;
  328.         if (fy)
  329.             inc = -1;
  330.         else
  331.         {
  332.             sprite += multi;
  333.             inc = 1;
  334.         }
  335.  
  336.         while (multi >= 0)
  337.         {
  338.             drawgfx(bitmap,Machine->gfx[3],
  339.                     sprite - multi * inc,
  340.                     colour,
  341.                     fx,fy,
  342.                     x,y - 16 * multi,
  343.                     &Machine->drv->visible_area,TRANSPARENCY_PEN,0);
  344.  
  345.             multi--;
  346.         }
  347.     }
  348. }
  349.  
  350. /******************************************************************************/
  351.  
  352. static void dec0_pf1_update(void)
  353. {
  354.     int offs,mx,my,color,tile,quarter;
  355.     int offsetx[4],offsety[4];
  356.  
  357.     switch (READ_WORD(&dec0_pf1_control_0[6])&0xf)
  358.     {
  359.         case 0:    /* 4x1 */
  360.             offsetx[0] = 0;
  361.             offsetx[1] = 256;
  362.             offsetx[2] = 512;
  363.             offsetx[3] = 768;
  364.             offsety[0] = 0;
  365.             offsety[1] = 0;
  366.             offsety[2] = 0;
  367.             offsety[3] = 0;
  368.             if (dec0_pf1_current_shape != 0)
  369.             {
  370.                 osd_free_bitmap(dec0_pf1_bitmap);
  371.                 dec0_pf1_bitmap = osd_create_bitmap(1024,256);
  372.                 dec0_pf1_current_shape = 0;
  373.                 memset(dec0_pf1_dirty,1,TEXTRAM_SIZE);
  374.             }
  375.             break;
  376.         case 1:    /* 2x2 */
  377.             offsetx[0] = 0;
  378.             offsetx[1] = 0;
  379.             offsetx[2] = 256;
  380.             offsetx[3] = 256;
  381.             offsety[0] = 0;
  382.             offsety[1] = 256;
  383.             offsety[2] = 0;
  384.             offsety[3] = 256;
  385.             if (dec0_pf1_current_shape != 1)
  386.             {
  387.                 osd_free_bitmap(dec0_pf1_bitmap);
  388.                 dec0_pf1_bitmap = osd_create_bitmap(512,512);
  389.                 dec0_pf1_current_shape = 1;
  390.                 memset(dec0_pf1_dirty,1,TEXTRAM_SIZE);
  391.             }
  392.             break;
  393.         case 2:    /* 1x4 */
  394.             offsetx[0] = 0;
  395.             offsetx[1] = 0;
  396.             offsetx[2] = 0;
  397.             offsetx[3] = 0;
  398.             offsety[0] = 0;
  399.             offsety[1] = 256;
  400.             offsety[2] = 512;
  401.             offsety[3] = 768;
  402.             if (dec0_pf1_current_shape != 2)
  403.             {
  404.                 osd_free_bitmap(dec0_pf1_bitmap);
  405.                 dec0_pf1_bitmap = osd_create_bitmap(256,1024);
  406.                 dec0_pf1_current_shape = 2;
  407.                 memset(dec0_pf1_dirty,1,TEXTRAM_SIZE);
  408.             }
  409.             break;
  410.         default:
  411.             logerror("error: pf1_update with unknown shape %04x\n",READ_WORD(&dec0_pf1_control_0[6]));
  412.             return;
  413.     }
  414.  
  415.     for (quarter = 0;quarter < 4;quarter++)
  416.     {
  417.         mx = -1;
  418.         my = 0;
  419.  
  420.         for (offs = 0x800 * quarter; offs < 0x800 * quarter + 0x800;offs += 2)
  421.         {
  422.             mx++;
  423.             if (mx == 32)
  424.             {
  425.                 mx = 0;
  426.                 my++;
  427.             }
  428.  
  429.             if (dec0_pf1_dirty[offs])
  430.             {
  431.                 dec0_pf1_dirty[offs] = 0;
  432.                 tile = READ_WORD(&dec0_pf1_data[offs]);
  433.                 color = (tile & 0xf000) >> 12;
  434.  
  435.                 drawgfx(dec0_pf1_bitmap,Machine->gfx[0],
  436.                         tile & 0x0fff,
  437.                         color,
  438.                         0,0,
  439.                         8*mx + offsetx[quarter],8*my + offsety[quarter],
  440.                         0,TRANSPARENCY_NONE,0);
  441.             }
  442.         }
  443.     }
  444. }
  445.  
  446. static void dec0_pf2_update(int transparent, int special)
  447. {
  448.     int offs,mx,my,color,tile,quarter;
  449.     int offsetx[4],offsety[4];
  450.     static int last_transparent;
  451.  
  452.     if (transparent != last_transparent)
  453.     {
  454.         last_transparent = transparent;
  455.         memset(dec0_pf2_dirty,1,TILERAM_SIZE);
  456.     }
  457.  
  458.     switch (READ_WORD(&dec0_pf2_control_0[6])&0xf)
  459.     {
  460.         case 0:    /* 4x1 */
  461.             offsetx[0] = 0;
  462.             offsetx[1] = 256;
  463.             offsetx[2] = 512;
  464.             offsetx[3] = 768;
  465.             offsety[0] = 0;
  466.             offsety[1] = 0;
  467.             offsety[2] = 0;
  468.             offsety[3] = 0;
  469.             if (dec0_pf2_current_shape != 0)
  470.             {
  471.                 osd_free_bitmap(dec0_pf2_bitmap);
  472.                 dec0_pf2_bitmap = osd_create_bitmap(1024,256);
  473.                 osd_free_bitmap(dec0_tf2_bitmap);
  474.                 dec0_tf2_bitmap = osd_create_bitmap(1024,256);
  475.                 dec0_pf2_current_shape = 0;
  476.                 memset(dec0_pf2_dirty,1,TILERAM_SIZE);
  477.             }
  478.             break;
  479.         case 1:    /* 2x2 */
  480.             offsetx[0] = 0;
  481.             offsetx[1] = 0;
  482.             offsetx[2] = 256;
  483.             offsetx[3] = 256;
  484.             offsety[0] = 0;
  485.             offsety[1] = 256;
  486.             offsety[2] = 0;
  487.             offsety[3] = 256;
  488.             if (dec0_pf2_current_shape != 1)
  489.             {
  490.                 osd_free_bitmap(dec0_pf2_bitmap);
  491.                 dec0_pf2_bitmap = osd_create_bitmap(512,512);
  492.                 osd_free_bitmap(dec0_tf2_bitmap);
  493.                 dec0_tf2_bitmap = osd_create_bitmap(512,512);
  494.                 dec0_pf2_current_shape = 1;
  495.                 memset(dec0_pf2_dirty,1,TILERAM_SIZE);
  496.             }
  497.             break;
  498.         case 2:    /* 1x4 */
  499.             offsetx[0] = 0;
  500.             offsetx[1] = 0;
  501.             offsetx[2] = 0;
  502.             offsetx[3] = 0;
  503.             offsety[0] = 0;
  504.             offsety[1] = 256;
  505.             offsety[2] = 512;
  506.             offsety[3] = 768;
  507.             if (dec0_pf2_current_shape != 2)
  508.             {
  509.                 osd_free_bitmap(dec0_pf2_bitmap);
  510.                 dec0_pf2_bitmap = osd_create_bitmap(256,1024);
  511.                 osd_free_bitmap(dec0_tf2_bitmap);
  512.                 dec0_tf2_bitmap = osd_create_bitmap(256,1024);
  513.                 dec0_pf2_current_shape = 2;
  514.                 memset(dec0_pf2_dirty,1,TILERAM_SIZE);
  515.             }
  516.             break;
  517.         default:
  518.             logerror("error: pf2_update with unknown shape %04x\n",READ_WORD(&dec0_pf2_control_0[6]));
  519.             return;
  520.     }
  521.  
  522.     for (quarter = 0;quarter < 4;quarter++)
  523.     {
  524.         mx = -1;
  525.         my = 0;
  526.  
  527.         for (offs = 0x200 * quarter; offs < 0x200 * quarter + 0x200;offs += 2)
  528.         {
  529.             mx++;
  530.             if (mx == 16)
  531.             {
  532.                 mx = 0;
  533.                 my++;
  534.             }
  535.  
  536.             if (dec0_pf2_dirty[offs])
  537.             {
  538.                 tile = READ_WORD(&dec0_pf2_data[offs]);
  539.                 color = (tile & 0xf000) >> 12;
  540.  
  541.                 /* 'Special' - Render foreground pens (8-15) to a seperate bitmap */
  542.                 if (special) {
  543.                     /* Blank tile */
  544.                     drawgfx(dec0_tf2_bitmap,Machine->gfx[3],
  545.                             0,
  546.                             0,
  547.                             0,0,
  548.                             16*mx + offsetx[quarter],16*my + offsety[quarter],
  549.                             0,TRANSPARENCY_NONE,0);
  550.  
  551.                     if (color>7)
  552.                         drawgfx(dec0_tf2_bitmap,Machine->gfx[1],
  553.                                 tile & 0x0fff,
  554.                                 color,
  555.                                 0,0,
  556.                                 16*mx + offsetx[quarter],16*my + offsety[quarter],
  557.                                 0,TRANSPARENCY_PENS,0xff);
  558.                 } else { /* Else, business as usual */
  559.                     dec0_pf2_dirty[offs] = 0;
  560.                     drawgfx(dec0_pf2_bitmap,Machine->gfx[1],
  561.                             tile & 0x0fff,
  562.                             color,
  563.                             0,0,
  564.                             16*mx + offsetx[quarter],16*my + offsety[quarter],
  565.                             0,TRANSPARENCY_NONE,0);
  566.                 }
  567.             }
  568.         }
  569.     }
  570. }
  571.  
  572. static void dec0_pf3_update(int transparent, int special)
  573. {
  574.     int offs,mx,my,color,tile,quarter;
  575.     int offsetx[4],offsety[4];
  576.     static int last_transparent;
  577.  
  578.     if (transparent != last_transparent)
  579.     {
  580.         last_transparent = transparent;
  581.         memset(dec0_pf3_dirty,1,TILERAM_SIZE);
  582.     }
  583.  
  584.     switch (READ_WORD(&dec0_pf3_control_0[6])&0xf)
  585.     {
  586.         case 0:    /* 4x1 */
  587.             offsetx[0] = 0;
  588.             offsetx[1] = 256;
  589.             offsetx[2] = 512;
  590.             offsetx[3] = 768;
  591.             offsety[0] = 0;
  592.             offsety[1] = 0;
  593.             offsety[2] = 0;
  594.             offsety[3] = 0;
  595.             if (dec0_pf3_current_shape != 0)
  596.             {
  597.                 osd_free_bitmap(dec0_pf3_bitmap);
  598.                 dec0_pf3_bitmap = osd_create_bitmap(1024,256);
  599.                 osd_free_bitmap(dec0_tf3_bitmap);
  600.                 dec0_tf3_bitmap = osd_create_bitmap(1024,256);
  601.                 dec0_pf3_current_shape = 0;
  602.                 memset(dec0_pf3_dirty,1,TILERAM_SIZE);
  603.             }
  604.             break;
  605.         case 1:    /* 2x2 */
  606.             offsetx[0] = 0;
  607.             offsetx[1] = 0;
  608.             offsetx[2] = 256;
  609.             offsetx[3] = 256;
  610.             offsety[0] = 0;
  611.             offsety[1] = 256;
  612.             offsety[2] = 0;
  613.             offsety[3] = 256;
  614.             if (dec0_pf3_current_shape != 1)
  615.             {
  616.                 osd_free_bitmap(dec0_pf3_bitmap);
  617.                 dec0_pf3_bitmap = osd_create_bitmap(512,512);
  618.                 osd_free_bitmap(dec0_tf3_bitmap);
  619.                 dec0_tf3_bitmap = osd_create_bitmap(512,512);
  620.                 dec0_pf3_current_shape = 1;
  621.                 memset(dec0_pf3_dirty,1,TILERAM_SIZE);
  622.             }
  623.             break;
  624.         case 2:    /* 1x4 */
  625.             offsetx[0] = 0;
  626.             offsetx[1] = 0;
  627.             offsetx[2] = 0;
  628.             offsetx[3] = 0;
  629.             offsety[0] = 0;
  630.             offsety[1] = 256;
  631.             offsety[2] = 512;
  632.             offsety[3] = 768;
  633.             if (dec0_pf3_current_shape != 2)
  634.             {
  635.                 osd_free_bitmap(dec0_pf3_bitmap);
  636.                 dec0_pf3_bitmap = osd_create_bitmap(256,1024);
  637.                 osd_free_bitmap(dec0_tf3_bitmap);
  638.                 dec0_tf3_bitmap = osd_create_bitmap(256,1024);
  639.                 dec0_pf3_current_shape = 2;
  640.                 memset(dec0_pf3_dirty,1,TILERAM_SIZE);
  641.             }
  642.             break;
  643.         default:
  644.             logerror("error: pf3_update with unknown shape %04x\n",READ_WORD(&dec0_pf3_control_0[6]));
  645.             return;
  646.     }
  647.  
  648.     for (quarter = 0;quarter < 4;quarter++)
  649.     {
  650.         mx = -1;
  651.         my = 0;
  652.  
  653.         for (offs = 0x200 * quarter; offs < 0x200 * quarter + 0x200;offs += 2)
  654.         {
  655.             mx++;
  656.             if (mx == 16)
  657.             {
  658.                 mx = 0;
  659.                 my++;
  660.             }
  661.  
  662.             if (dec0_pf3_dirty[offs])
  663.             {
  664.                 tile = READ_WORD(&dec0_pf3_data[offs]);
  665.                 color = (tile & 0xf000) >> 12;
  666.  
  667.                 /* 'Special' - Render foreground pens (8-15) to a seperate bitmap */
  668.                 if (special) {
  669.                     /* Blank tile */
  670.                     drawgfx(dec0_tf3_bitmap,Machine->gfx[3],
  671.                             0,
  672.                             0,
  673.                             0,0,
  674.                             16*mx + offsetx[quarter],16*my + offsety[quarter],
  675.                             0,TRANSPARENCY_NONE,0);
  676.  
  677.                     if (color>7)
  678.                         drawgfx(dec0_tf3_bitmap,Machine->gfx[2],
  679.                             tile & 0x0fff,
  680.                             color,
  681.                             0,0,
  682.                             16*mx + offsetx[quarter],16*my + offsety[quarter],
  683.                             0,TRANSPARENCY_PENS,0xff);
  684.                 } else { /* Else, business as usual */
  685.                     dec0_pf3_dirty[offs] = 0;
  686.                     drawgfx(dec0_pf3_bitmap,Machine->gfx[2],
  687.                             tile & 0x0fff,
  688.                             color,
  689.                             0,0,
  690.                             16*mx + offsetx[quarter],16*my + offsety[quarter],
  691.                             0,TRANSPARENCY_NONE,0);
  692.                 }
  693.             }
  694.         }
  695.     }
  696. }
  697.  
  698. /******************************************************************************/
  699.  
  700. void dec0_pf1_draw(struct osd_bitmap *bitmap)
  701. {
  702.     int offs,lines,height,scrolly,scrollx;
  703.  
  704.     scrollx = - READ_WORD(&dec0_pf1_control_1[0]);
  705.     scrolly = - READ_WORD(&dec0_pf1_control_1[2]);
  706.  
  707.     /* We check for column scroll and use that if needed, otherwise use row scroll,
  708.        I am 99% sure they are never needed at same time ;) */
  709.     if (READ_WORD(&dec0_pf1_colscroll[0])) /* This is NOT a good check for col scroll, I can't find real bit */
  710.     {
  711.         int cscrolly[64];
  712.  
  713.         for (offs = 0;offs < 32;offs++)
  714.         cscrolly[offs] = -READ_WORD(&dec0_pf1_control_1[2]) - READ_WORD(&dec0_pf1_colscroll[2*offs]);
  715.  
  716.         copyscrollbitmap(bitmap,dec0_pf1_bitmap,1,&scrollx,32,cscrolly,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  717.     }
  718.  
  719.     /* Row scroll enable bit (unsure if this enables/disables col scroll too) */
  720.     else if (READ_WORD(&dec0_pf1_control_0[0])&0x4)
  721.     {
  722.         int rscrollx[1024];
  723.  
  724.         /* Playfield shape */
  725.         switch (READ_WORD(&dec0_pf1_control_0[6])&0xf)
  726.         {
  727.             case 0:    height=1; break; /* 4x1, 256 rows */
  728.             case 1:    height=2; break; /* 2x2, 512 rows */
  729.             case 2:    height=4; break; /* 1x4, 1024 rows */
  730.             default: height=2; break; /* Never happens (I hope) */
  731.         }
  732.  
  733.         /* Rowscroll style */
  734.         switch (READ_WORD(&dec0_pf1_control_1[6])&0xf)
  735.         {
  736.             case 0: lines=256; break; /* 256 horizontal scroll registers (Robocop) */
  737.             case 1: lines=128; break; /* 128 horizontal scroll registers (Not used?) */
  738.             case 2: lines=64; break; /* 128 horizontal scroll registers (Not used?) */
  739.             case 3: lines=32; break; /* 32 horizontal scroll registers (Heavy Barrel title screen) */
  740.             case 4: lines=16; break; /* 16 horizontal scroll registers (Bad Dudes, Sly Spy) */
  741.             case 5: lines=8; break; /* 8 horizontal scroll registers (Not used?) */
  742.             case 6: lines=4; break; /* 4 horizontal scroll registers (Not used?) */
  743.             case 7: lines=2; break; /* 2 horizontal scroll registers (Not used?) */
  744.             case 8: lines=1; break; /* Appears to be no row-scroll - so maybe only bottom 3 bits are style */
  745.             default: lines=1; break; /* Just in case */
  746.         }
  747.  
  748.         for (offs = 0; offs < lines*height; offs++)
  749.             rscrollx[offs] = scrollx - READ_WORD(&dec0_pf1_rowscroll[offs<<1]);
  750.         copyscrollbitmap(bitmap,dec0_pf1_bitmap,lines*height,rscrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  751.     }
  752.     else /* Scroll registers not enabled */
  753.         copyscrollbitmap(bitmap,dec0_pf1_bitmap,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  754. }
  755.  
  756. /* trans=0 - bottom playfield, trans=1 - top playfield, trans=2 - special foreground section */
  757. void dec0_pf2_draw(struct osd_bitmap *bitmap, int trans)
  758. {
  759.     int offs,lines,height,width,scrolly,scrollx;
  760.  
  761.     scrollx = - READ_WORD(&dec0_pf2_control_1[0]);
  762.     scrolly = - READ_WORD(&dec0_pf2_control_1[2]);
  763.  
  764.     /* Row scroll enable bit */
  765.     if (READ_WORD(&dec0_pf2_control_0[0])&0x4)
  766.     {
  767.         int rscrollx[1024];
  768.  
  769.         /* Playfield shape */
  770.         switch (READ_WORD(&dec0_pf2_control_0[6])&0xf)
  771.         {
  772.             case 0:    height=1; break; /* 4x1, 256 rows */
  773.             case 1:    height=2; break; /* 2x2, 512 rows */
  774.             case 2:    height=4; break; /* 1x4, 1024 rows */
  775.             default: height=2; break; /* Never happens (I hope) */
  776.         }
  777.  
  778.         /* Rowscroll style */
  779.         switch (READ_WORD(&dec0_pf2_control_1[6])&0xf)
  780.         {
  781.             case 0: lines=256; break; /* 256 horizontal scroll registers (Robocop) */
  782.             case 1: lines=128; break; /* 128 horizontal scroll registers (Not used?) */
  783.             case 2: lines=64; break; /* 128 horizontal scroll registers (Not used?) */
  784.             case 3: lines=32; break; /* 32 horizontal scroll registers (Heavy Barrel title screen) */
  785.             case 4: lines=16; break; /* 16 horizontal scroll registers (Bad Dudes, Sly Spy) */
  786.             case 5: lines=8; break; /* 8 horizontal scroll registers (Not used?) */
  787.             case 6: lines=4; break; /* 4 horizontal scroll registers (Not used?) */
  788.             case 7: lines=2; break; /* 2 horizontal scroll registers (Not used?) */
  789.             case 8: lines=1; break; /* Appears to be no row-scroll */
  790.             default: lines=1; break; /* Just in case */
  791.         }
  792.  
  793.         for (offs = 0; offs < lines*height; offs++)
  794.             rscrollx[offs] = scrollx - READ_WORD(&dec0_pf2_rowscroll[offs<<1]);
  795.  
  796.         if (trans==2)
  797.             copyscrollbitmap(bitmap,dec0_tf2_bitmap,lines*height,rscrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  798.         else if (trans==1)
  799.             copyscrollbitmap(bitmap,dec0_pf2_bitmap,lines*height,rscrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  800.         else
  801.             copyscrollbitmap(bitmap,dec0_pf2_bitmap,lines*height,rscrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  802.     }
  803.     else /* Column scroll enable bit */
  804.     if (READ_WORD(&dec0_pf2_control_0[0])&0x8)
  805.     {
  806.         int rscrollx[1024];
  807.  
  808.         /* Playfield shape */
  809.         switch (READ_WORD(&dec0_pf2_control_0[6])&0xf)
  810.         {
  811.             case 0:    width=1; break; /* 4x1, 256 rows */
  812.             case 1:    width=2; break; /* 2x2, 512 rows */
  813.             case 2:    width=4; break; /* 1x4, 1024 rows */
  814.             default: width=2; break; /* Never happens (I hope) */
  815.         }
  816.  
  817.         /* Rowscroll style */
  818.         switch (READ_WORD(&dec0_pf2_control_1[4])&0xf)
  819.         {
  820.             case 0: lines=64; break; /* 256 horizontal scroll registers (Robocop) */
  821.             case 1: lines=32; break; /* 128 horizontal scroll registers (Not used?) */
  822.             case 2: lines=16; break; /* 128 horizontal scroll registers (Not used?) */
  823.             case 3: lines=8; break; /* 32 horizontal scroll registers (Heavy Barrel title screen) */
  824.             case 4: lines=4; break; /* 16 horizontal scroll registers (Bad Dudes, Sly Spy) */
  825.             case 5: lines=2; break; /* 8 horizontal scroll registers (Not used?) */
  826.             case 6: lines=1; break; /* 4 horizontal scroll registers (Not used?) */
  827.             case 7: lines=2; break; /* 2 horizontal scroll registers (Not used?) */
  828.             case 8: lines=1; break; /* Appears to be no row-scroll */
  829.             default: lines=1; break; /* Just in case */
  830.         }
  831.  
  832.         for (offs = 0; offs < lines; offs++)
  833.             rscrollx[offs] = scrolly - READ_WORD(&dec0_pf2_colscroll[offs<<1]);
  834.  
  835.         if (trans==2)
  836.             copyscrollbitmap(bitmap,dec0_tf2_bitmap,1,&scrollx,lines,rscrollx,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  837.         else if (trans==1)
  838.             copyscrollbitmap(bitmap,dec0_pf2_bitmap,1,&scrollx,lines,rscrollx,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  839.         else
  840.             copyscrollbitmap(bitmap,dec0_pf2_bitmap,1,&scrollx,lines,rscrollx,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  841.     }
  842.     else { /* Scroll registers not enabled */
  843.         if (trans==2)
  844.             copyscrollbitmap(bitmap,dec0_tf2_bitmap,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  845.         else if (trans==1)
  846.             copyscrollbitmap(bitmap,dec0_pf2_bitmap,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  847.         else
  848.             copyscrollbitmap(bitmap,dec0_pf2_bitmap,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  849.     }
  850. }
  851.  
  852. void dec0_pf3_draw(struct osd_bitmap *bitmap, int trans)
  853. {
  854.     int offs,lines,height,scrolly,scrollx;
  855.  
  856.     scrollx = - READ_WORD(&dec0_pf3_control_1[0]);
  857.     scrolly = - READ_WORD(&dec0_pf3_control_1[2]);
  858.  
  859.     /* Colscroll not supported for this playfield (does anything use it?) */
  860.  
  861.     /* Row scroll enable bit (unsure if this enables/disables col scroll too) */
  862.     if (READ_WORD(&dec0_pf3_control_0[0])&0x4)
  863.     {
  864.         int rscrollx[1024];
  865.  
  866.         /* Playfield shape */
  867.         switch (READ_WORD(&dec0_pf3_control_0[6])&0xf)
  868.         {
  869.             case 0:    height=1; break; /* 4x1, 256 rows */
  870.             case 1:    height=2; break; /* 2x2, 512 rows */
  871.             case 2:    height=4; break; /* 1x4, 1024 rows */
  872.             default: height=2; break; /* Never happens (I hope) */
  873.         }
  874.  
  875.         /* Rowscroll style */
  876.         switch (READ_WORD(&dec0_pf3_control_1[6])&0xf)
  877.         {
  878.             case 0: lines=256; break; /* 256 horizontal scroll registers (Robocop) */
  879.             case 1: lines=128; break; /* 128 horizontal scroll registers (Not used?) */
  880.             case 2: lines=64; break; /* 128 horizontal scroll registers (Not used?) */
  881.             case 3: lines=32; break; /* 32 horizontal scroll registers (Heavy Barrel title screen) */
  882.             case 4: lines=16; break; /* 16 horizontal scroll registers (Bad Dudes, Sly Spy) */
  883.             case 5: lines=8; break; /* 8 horizontal scroll registers (Not used?) */
  884.             case 6: lines=4; break; /* 4 horizontal scroll registers (Not used?) */
  885.             case 7: lines=2; break; /* 2 horizontal scroll registers (Not used?) */
  886.             case 8: lines=1; break; /* Appears to be no row-scroll - so maybe only bottom 3 bits are style */
  887.             default: lines=1; break; /* Just in case */
  888.         }
  889.  
  890.         for (offs = 0; offs < lines*height; offs++)
  891.             rscrollx[offs] = scrollx - READ_WORD(&dec0_pf3_rowscroll[offs<<1]);
  892.  
  893.         if (trans==2)
  894.             copyscrollbitmap(bitmap,dec0_tf3_bitmap,lines*height,rscrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  895.         else if (trans==1)
  896.             copyscrollbitmap(bitmap,dec0_pf3_bitmap,lines*height,rscrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  897.         else
  898.             copyscrollbitmap(bitmap,dec0_pf3_bitmap,lines*height,rscrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  899.     }
  900.     else { /* Scroll registers not enabled */
  901.         if (trans==2)
  902.             copyscrollbitmap(bitmap,dec0_tf3_bitmap,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  903.         else if (trans==1)
  904.             copyscrollbitmap(bitmap,dec0_pf3_bitmap,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
  905.         else
  906.             copyscrollbitmap(bitmap,dec0_pf3_bitmap,1,&scrollx,1,&scrolly,&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
  907.     }
  908. }
  909.  
  910. /******************************************************************************/
  911.  
  912. void hbarrel_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  913. {
  914.     dec0_update_palette(dec0_pri & 0x01);
  915.  
  916.     dec0_pf1_update();
  917.     dec0_pf3_update(0,0);
  918.     dec0_pf2_update(1,0);
  919.     dec0_pf3_draw(bitmap,0);
  920.     dec0_drawsprites(bitmap,0x08,0x08);
  921.     dec0_pf2_draw(bitmap,1);
  922.  
  923.     /* HB always keeps pf2 on top of pf3, no need explicitly support priority register */
  924.  
  925.     dec0_drawsprites(bitmap,0x08,0x00);
  926.     dec0_pf1_draw(bitmap);
  927. }
  928.  
  929. /******************************************************************************/
  930.  
  931. void baddudes_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  932. {
  933.     /* WARNING: priority inverted wrt all the other games */
  934.     dec0_update_palette(~dec0_pri & 0x01);
  935.     dec0_pf1_update();
  936.  
  937.     /* WARNING: inverted wrt Midnight Resistance */
  938.     if ((dec0_pri & 0x01) == 0)
  939.     {
  940.         dec0_pf2_update(0,1); /* Foreground pens of pf2 only */
  941.         dec0_pf2_update(0,0);
  942.         dec0_pf3_update(1,1);
  943.         dec0_pf3_update(1,0);
  944.  
  945.         dec0_pf2_draw(bitmap,0);
  946.         dec0_pf3_draw(bitmap,1);
  947.  
  948.         if (dec0_pri & 2)
  949.             dec0_pf2_draw(bitmap,2); /* Foreground pens only */
  950.  
  951.         dec0_drawsprites(bitmap,0x00,0x00);
  952.  
  953.         if (dec0_pri & 4)
  954.             dec0_pf3_draw(bitmap,2); /* Foreground pens only */
  955.     }
  956.     else
  957.     {
  958.         dec0_pf3_update(0,1);
  959.         dec0_pf3_update(0,0);
  960.         dec0_pf2_update(1,1);
  961.         dec0_pf2_update(1,0);
  962.  
  963.         dec0_pf3_draw(bitmap,0);
  964.         dec0_pf2_draw(bitmap,1);
  965.  
  966.         if (dec0_pri & 2)
  967.             dec0_pf3_draw(bitmap,2);
  968.  
  969.         dec0_drawsprites(bitmap,0x00,0x00);
  970.  
  971.         if (dec0_pri & 4)
  972.             dec0_pf2_draw(bitmap,2);
  973.     }
  974.  
  975.     dec0_pf1_draw(bitmap);
  976. }
  977.  
  978. /******************************************************************************/
  979.  
  980. void robocop_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  981. {
  982.     dec0_update_palette(dec0_pri & 0x01);
  983.     dec0_pf1_update();
  984.  
  985.     if (dec0_pri & 0x01)
  986.     {
  987.         int trans;
  988.  
  989.         dec0_pf2_update(0,0);
  990.         dec0_pf3_update(1,0);
  991.  
  992.         /* WARNING: inverted wrt Midnight Resistance */
  993.         /* Robocop uses it only for the title screen, so this might be just */
  994.         /* completely wrong. The top 8 bits of the register might mean */
  995.         /* something (they are 0x80 in midres, 0x00 here) */
  996.         if (dec0_pri & 0x04)
  997.             trans = 0x08;
  998.         else trans = 0x00;
  999.  
  1000.         dec0_pf2_draw(bitmap,0);
  1001.  
  1002.         if (dec0_pri & 0x02)
  1003.             dec0_drawsprites(bitmap,0x08,trans);
  1004.  
  1005.         dec0_pf3_draw(bitmap,1);
  1006.  
  1007.         if (dec0_pri & 0x02)
  1008.             dec0_drawsprites(bitmap,0x08,trans ^ 0x08);
  1009.         else
  1010.             dec0_drawsprites(bitmap,0x00,0x00);
  1011.     }
  1012.     else
  1013.     {
  1014.         int trans;
  1015.  
  1016.         dec0_pf3_update(0,0);
  1017.         dec0_pf2_update(1,0);
  1018.  
  1019.         /* WARNING: inverted wrt Midnight Resistance */
  1020.         /* Robocop uses it only for the title screen, so this might be just */
  1021.         /* completely wrong. The top 8 bits of the register might mean */
  1022.         /* something (they are 0x80 in midres, 0x00 here) */
  1023.         if (dec0_pri & 0x04)
  1024.             trans = 0x08;
  1025.         else trans = 0x00;
  1026.  
  1027.         dec0_pf3_draw(bitmap,0);
  1028.  
  1029.         if (dec0_pri & 0x02)
  1030.             dec0_drawsprites(bitmap,0x08,trans);
  1031.  
  1032.         dec0_pf2_draw(bitmap,1);
  1033.  
  1034.         if (dec0_pri & 0x02)
  1035.             dec0_drawsprites(bitmap,0x08,trans ^ 0x08);
  1036.         else
  1037.             dec0_drawsprites(bitmap,0x00,0x00);
  1038.     }
  1039.  
  1040.     dec0_pf1_draw(bitmap);
  1041.  
  1042. }
  1043.  
  1044. /******************************************************************************/
  1045.  
  1046. void birdtry_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  1047. {
  1048.     dec0_update_palette(dec0_pri & 0x01);
  1049.  
  1050.     /* This game doesn't have the extra playfield chip on the game board */
  1051.     dec0_pf1_update();
  1052.     dec0_pf2_update(0,0);
  1053.     dec0_pf2_draw(bitmap,0);
  1054.     dec0_drawsprites(bitmap,0x00,0x00);
  1055.     dec0_pf1_draw(bitmap);
  1056. }
  1057.  
  1058. /******************************************************************************/
  1059.  
  1060. void hippodrm_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  1061. {
  1062.     dec0_update_palette(dec0_pri & 0x01);
  1063.     dec0_pf1_update();
  1064.  
  1065.     if (dec0_pri & 0x01)
  1066.     {
  1067.         dec0_pf2_update(0,0);
  1068.         dec0_pf3_update(1,0);
  1069.  
  1070.         dec0_pf2_draw(bitmap,0);
  1071.         dec0_pf3_draw(bitmap,1);
  1072.     }
  1073.     else
  1074.     {
  1075.         dec0_pf3_update(0,0);
  1076.         dec0_pf2_update(1,0);
  1077.  
  1078.         dec0_pf3_draw(bitmap,0);
  1079.         dec0_pf2_draw(bitmap,1);
  1080.     }
  1081.  
  1082.     dec0_drawsprites(bitmap,0x00,0x00);
  1083.     dec0_pf1_draw(bitmap);
  1084. }
  1085.  
  1086. /******************************************************************************/
  1087.  
  1088. void slyspy_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  1089. {
  1090.     dec0_update_palette(0);
  1091.  
  1092.     dec0_pf1_update();
  1093.     dec0_pf3_update(0,0);
  1094.     dec0_pf2_update(1,1);
  1095.     dec0_pf2_update(1,0);
  1096.  
  1097.     dec0_pf3_draw(bitmap,0);
  1098.     dec0_pf2_draw(bitmap,1);
  1099.  
  1100.     dec0_drawsprites(bitmap,0x00,0x00);
  1101.  
  1102.     if (dec0_pri&0x80)
  1103.         dec0_pf2_draw(bitmap,2);
  1104.  
  1105.     dec0_pf1_draw(bitmap);
  1106. }
  1107.  
  1108. /******************************************************************************/
  1109.  
  1110. void midres_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  1111. {
  1112.     dec0_update_palette(dec0_pri & 0x01);
  1113.     dec0_pf1_update();
  1114.  
  1115. if (dec0_pri & 0x01)
  1116. {
  1117.     int trans;
  1118.  
  1119.     dec0_pf2_update(0,0);
  1120.     dec0_pf3_update(1,0);
  1121.  
  1122.     if (dec0_pri & 0x04)
  1123.         trans = 0x00;
  1124.     else trans = 0x08;
  1125.  
  1126.     dec0_pf2_draw(bitmap,0);
  1127.  
  1128.     if (dec0_pri & 0x02)
  1129.         dec0_drawsprites(bitmap,0x08,trans);
  1130.  
  1131.     dec0_pf3_draw(bitmap,1);
  1132.  
  1133.     if (dec0_pri & 0x02)
  1134.         dec0_drawsprites(bitmap,0x08,trans ^ 0x08);
  1135.     else
  1136.         dec0_drawsprites(bitmap,0x00,0x00);
  1137. }
  1138. else
  1139. {
  1140.     int trans;
  1141.  
  1142.     dec0_pf3_update(0,0);
  1143.     dec0_pf2_update(1,0);
  1144.  
  1145.     if (dec0_pri & 0x04)
  1146.         trans = 0x00;
  1147.     else trans = 0x08;
  1148.  
  1149.     dec0_pf3_draw(bitmap,0);
  1150.  
  1151.     if (dec0_pri & 0x02)
  1152.         dec0_drawsprites(bitmap,0x08,trans);
  1153.  
  1154.     dec0_pf2_draw(bitmap,1);
  1155.  
  1156.     if (dec0_pri & 0x02)
  1157.         dec0_drawsprites(bitmap,0x08,trans ^ 0x08);
  1158.     else
  1159.         dec0_drawsprites(bitmap,0x00,0x00);
  1160.     }
  1161.  
  1162.     dec0_pf1_draw(bitmap);
  1163. }
  1164.  
  1165. /******************************************************************************/
  1166.  
  1167. WRITE_HANDLER( dec0_pf1_control_0_w )
  1168. {
  1169.     COMBINE_WORD_MEM(&dec0_pf1_control_0[offset],data);
  1170. }
  1171.  
  1172. WRITE_HANDLER( dec0_pf1_control_1_w )
  1173. {
  1174.     COMBINE_WORD_MEM(&dec0_pf1_control_1[offset],data);
  1175. }
  1176.  
  1177. WRITE_HANDLER( dec0_pf1_rowscroll_w )
  1178. {
  1179.     COMBINE_WORD_MEM(&dec0_pf1_rowscroll[offset],data);
  1180. }
  1181.  
  1182. WRITE_HANDLER( dec0_pf1_colscroll_w )
  1183. {
  1184.     COMBINE_WORD_MEM(&dec0_pf1_colscroll[offset],data);
  1185. }
  1186.  
  1187. WRITE_HANDLER( dec0_pf1_data_w )
  1188. {
  1189.     int oldword = READ_WORD(&dec0_pf1_data[offset]);
  1190.     int newword = COMBINE_WORD(oldword,data);
  1191.  
  1192.     if (oldword != newword)
  1193.     {
  1194.         WRITE_WORD(&dec0_pf1_data[offset],newword);
  1195.         dec0_pf1_dirty[offset] = 1;
  1196.     }
  1197. }
  1198.  
  1199. READ_HANDLER( dec0_pf1_data_r )
  1200. {
  1201.     return READ_WORD(&dec0_pf1_data[offset]);
  1202. }
  1203.  
  1204. WRITE_HANDLER( dec0_pf2_control_0_w )
  1205. {
  1206.     COMBINE_WORD_MEM(&dec0_pf2_control_0[offset],data);
  1207. }
  1208.  
  1209. WRITE_HANDLER( dec0_pf2_control_1_w )
  1210. {
  1211.     COMBINE_WORD_MEM(&dec0_pf2_control_1[offset],data);
  1212. }
  1213.  
  1214. WRITE_HANDLER( dec0_pf2_rowscroll_w )
  1215. {
  1216.     COMBINE_WORD_MEM(&dec0_pf2_rowscroll[offset],data);
  1217. }
  1218.  
  1219. WRITE_HANDLER( dec0_pf2_colscroll_w )
  1220. {
  1221.     COMBINE_WORD_MEM(&dec0_pf2_colscroll[offset],data);
  1222. }
  1223.  
  1224. WRITE_HANDLER( dec0_pf2_data_w )
  1225. {
  1226.     int oldword = READ_WORD(&dec0_pf2_data[offset]);
  1227.     int newword = COMBINE_WORD(oldword,data);
  1228.  
  1229.     if (oldword != newword)
  1230.     {
  1231.         WRITE_WORD(&dec0_pf2_data[offset],newword);
  1232.         dec0_pf2_dirty[offset] = 1;
  1233.     }
  1234. }
  1235.  
  1236. READ_HANDLER( dec0_pf2_data_r )
  1237. {
  1238.     return READ_WORD(&dec0_pf2_data[offset]);
  1239. }
  1240.  
  1241. WRITE_HANDLER( dec0_pf3_control_0_w )
  1242. {
  1243.     COMBINE_WORD_MEM(&dec0_pf3_control_0[offset],data);
  1244. }
  1245.  
  1246. WRITE_HANDLER( dec0_pf3_control_1_w )
  1247. {
  1248.     COMBINE_WORD_MEM(&dec0_pf3_control_1[offset],data);
  1249. }
  1250.  
  1251. WRITE_HANDLER( dec0_pf3_rowscroll_w )
  1252. {
  1253.     COMBINE_WORD_MEM(&dec0_pf3_rowscroll[offset],data);
  1254. }
  1255.  
  1256. WRITE_HANDLER( dec0_pf3_colscroll_w )
  1257. {
  1258.     COMBINE_WORD_MEM(&dec0_pf3_colscroll[offset],data);
  1259. }
  1260.  
  1261. READ_HANDLER( dec0_pf3_colscroll_r )
  1262. {
  1263.     return READ_WORD(&dec0_pf3_colscroll[offset]);
  1264. }
  1265.  
  1266. WRITE_HANDLER( dec0_pf3_data_w )
  1267. {
  1268.     int oldword = READ_WORD(&dec0_pf3_data[offset]);
  1269.     int newword = COMBINE_WORD(oldword,data);
  1270.  
  1271.     if (oldword != newword)
  1272.     {
  1273.         WRITE_WORD(&dec0_pf3_data[offset],newword);
  1274.         dec0_pf3_dirty[offset] = 1;
  1275.     }
  1276. }
  1277.  
  1278. READ_HANDLER( dec0_pf3_data_r )
  1279. {
  1280.     return READ_WORD(&dec0_pf3_data[offset]);
  1281. }
  1282.  
  1283. WRITE_HANDLER( dec0_priority_w )
  1284. {
  1285.       dec0_pri = COMBINE_WORD(dec0_pri,data);
  1286. }
  1287.  
  1288. WRITE_HANDLER( dec0_pf3_control_8bit_w )
  1289. {
  1290.     static int buffer[0x20];
  1291.     int myword;
  1292.  
  1293.     buffer[offset]=data;
  1294.  
  1295.     /* Rearrange little endian bytes from H6280 into big endian words for 68k */
  1296.     offset&=0xffe;
  1297.     myword=buffer[offset] + (buffer[offset+1]<<8);
  1298.  
  1299.     if (offset<0x10) dec0_pf3_control_0_w(offset,myword);
  1300.     else dec0_pf3_control_1_w(offset-0x10,myword);
  1301. }
  1302.  
  1303. WRITE_HANDLER( dec0_pf3_data_8bit_w )
  1304. {
  1305.     if (offset&1) { /* MSB has changed */
  1306.         int lsb=READ_WORD(&dec0_pf3_data[offset&0x7fe]);
  1307.         int newword=(lsb&0xff) | (data<<8);
  1308.         WRITE_WORD(&dec0_pf3_data[offset&0x7fe],newword);
  1309.         dec0_pf3_dirty[offset&0x7fe] = 1;
  1310.     }
  1311.     else { /* LSB has changed */
  1312.         int msb=READ_WORD(&dec0_pf3_data[offset&0x7fe]);
  1313.         int newword=(msb&0xff00) | data;
  1314.         WRITE_WORD(&dec0_pf3_data[offset&0x7fe],newword);
  1315.         dec0_pf3_dirty[offset&0x7fe] = 1;
  1316.     }
  1317. }
  1318.  
  1319. READ_HANDLER( dec0_pf3_data_8bit_r )
  1320. {
  1321.     if (offset&1) /* MSB */
  1322.         return READ_WORD(&dec0_pf3_data[offset&0x7fe])>>8;
  1323.  
  1324.     return READ_WORD(&dec0_pf3_data[offset&0x7fe])&0xff;;
  1325. }
  1326.  
  1327. /******************************************************************************/
  1328.  
  1329. void dec0_nodma_vh_stop (void)
  1330. {
  1331.     osd_free_bitmap(dec0_pf3_bitmap);
  1332.     osd_free_bitmap(dec0_pf2_bitmap);
  1333.     osd_free_bitmap(dec0_pf1_bitmap);
  1334.     osd_free_bitmap(dec0_tf2_bitmap);
  1335.     osd_free_bitmap(dec0_tf3_bitmap);
  1336.     free(dec0_pf3_dirty);
  1337.     free(dec0_pf2_dirty);
  1338.     free(dec0_pf1_dirty);
  1339. }
  1340.  
  1341. void dec0_vh_stop (void)
  1342. {
  1343.     free(dec0_spriteram);
  1344.     dec0_nodma_vh_stop();
  1345. }
  1346.  
  1347. int dec0_nodma_vh_start (void)
  1348. {
  1349.     /* Allocate bitmaps */
  1350.     if ((dec0_pf1_bitmap = osd_create_bitmap(512,512)) == 0) {
  1351.         dec0_vh_stop ();
  1352.         return 1;
  1353.     }
  1354.     dec0_pf1_current_shape = 1;
  1355.  
  1356.     if ((dec0_pf2_bitmap = osd_create_bitmap(512,512)) == 0) {
  1357.         dec0_vh_stop ();
  1358.         return 1;
  1359.     }
  1360.     dec0_pf2_current_shape = 1;
  1361.  
  1362.     if ((dec0_pf3_bitmap = osd_create_bitmap(512,512)) == 0) {
  1363.         dec0_vh_stop ();
  1364.         return 1;
  1365.     }
  1366.     dec0_pf3_current_shape = 1;
  1367.  
  1368.     if ((dec0_tf2_bitmap = osd_create_bitmap(512,512)) == 0) {
  1369.         dec0_vh_stop ();
  1370.         return 1;
  1371.     }
  1372.  
  1373.     if ((dec0_tf3_bitmap = osd_create_bitmap(512,512)) == 0) {
  1374.         dec0_vh_stop ();
  1375.         return 1;
  1376.     }
  1377.  
  1378.     dec0_pf1_dirty = malloc(TEXTRAM_SIZE);
  1379.     dec0_pf3_dirty = malloc(TILERAM_SIZE);
  1380.     dec0_pf2_dirty = malloc(TILERAM_SIZE);
  1381.  
  1382.     memset(dec0_pf1_dirty,1,TEXTRAM_SIZE);
  1383.     memset(dec0_pf2_dirty,1,TILERAM_SIZE);
  1384.     memset(dec0_pf3_dirty,1,TILERAM_SIZE);
  1385.  
  1386.     dec0_spriteram=spriteram;
  1387.  
  1388.     return 0;
  1389. }
  1390.  
  1391. int dec0_vh_start (void)
  1392. {
  1393.     dec0_nodma_vh_start();
  1394.     dec0_spriteram=malloc(0x800);
  1395.  
  1396.     return 0;
  1397. }
  1398.  
  1399. /******************************************************************************/
  1400.  
  1401.